package com.xysoft.admin.service.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.xysoft.admin.SessionContext;
import com.xysoft.admin.common.SessionInfo;
import com.xysoft.admin.dto.MenuDTO;
import com.xysoft.admin.dto.MenuDetailDTO;
import com.xysoft.admin.service.IHomeService;
import com.xysoft.model.Action;
import com.xysoft.model.ActionColumn;
import com.xysoft.model.Organization;
import com.xysoft.model.RoleAction;
import com.xysoft.model.User;
import com.xysoft.model.UserAction;
import com.xysoft.model.UserRole;
import com.xysoft.util.DateUtil;
import com.xysoft.util.Encrypt;
import com.xysoft.util.IpUtil;
import com.xysoft.util.JsonUtil;
import com.xysoft.util.RequestUtil;
import com.xysoft.util.ResourceUtil;

@Component
@SuppressWarnings("unchecked")
public class HomeServiceImpl extends BaseServiceImpl implements IHomeService {
	
	@Transactional
	public String login(User user, HttpServletRequest request, HttpSession session) {
		List<User> users = this.getBaseDao().find("from User u where username = ? and password = ? and enabled = 1", 
				user.getUsername(), Encrypt.md5AndSha(user.getPassword()));
		if (users.size() > 0) {
			User userlogin = users.get(0);
			userlogin.setIp(IpUtil.getIpAddr(request));
			this.getBaseDao().save(userlogin);
			SessionInfo sessionInfo = new SessionInfo();
			sessionInfo.setUser(userlogin);
			//存放拥有权限
			List<String> actions = new ArrayList<String>();
			sessionInfo.setActions(actions);
			sessionInfo.setId(session.getId());
			Organization organ = userlogin.getOrganization();
			sessionInfo.setOrgId(organ.getId());
			sessionInfo.setKeyChar(organ.getKeyChar());
			sessionInfo.setTypeValue(organ.getSystemType().getValue());
			session.setAttribute(ResourceUtil.getSessionInfoName(), session.getId());
			SessionContext myc= SessionContext.getInstance();
			myc.AddSession(sessionInfo);
			return "success";
		}
		return null;
	}

	@Transactional
	public String menu(HttpServletRequest request, HttpSession session) {
		SessionInfo sessionInfo = RequestUtil.getSession(request, session);
		User userlogin = sessionInfo.getUser();
		User user = (User)this.getBaseDao().get(User.class, userlogin.getId());
		//角色权限
		List<String> actions = new ArrayList<String>();
		//按钮权限
		Map<Integer, List<String>> buttons = new HashMap<Integer, List<String>>();
		//List<String> buttons = new ArrayList<String>();
		Map<Integer, String> maps = new HashMap<Integer, String>();
		Set<UserRole> urs = user.getUserRoles();
		for (UserRole ur : urs) {
			Set<RoleAction> acts = ur.getRole().getRoleActions();
			for(RoleAction act : acts) {
				Action action= act.getAction();
				if (actions.indexOf(action.getCode()) == -1) {
					actions.add(action.getCode());
					Integer colId = action.getColumn().getId();
					List<String> temp = null;
					if (buttons.containsKey(colId)) {
						temp = buttons.get(colId);
					} else {
						temp = new ArrayList<String>();
					}
					temp.add(action.getKeyButton());
					buttons.put(colId, temp);
					//buttons.add(action.getKeyButton());
					if (action.isLeaf()) {
						String code = RequestUtil.getActionUrl(action.getCode());
						maps.put(colId, code);
						//actions.add(code);
					}
				}
			}
		}
		//用户权限
		Set<UserAction> uas = user.getUserActions();
		for (UserAction ua : uas) {
			Action action= ua.getAction();
			if (ua.isEnable()) {
				if (actions.indexOf(action.getCode()) == -1) {
					actions.add(action.getCode());
					Integer colId = action.getColumn().getId();
					List<String> temp = null;
					if (buttons.containsKey(colId)) {
						temp = buttons.get(colId);
					} else {
						temp = new ArrayList<String>();
					}
					temp.add(action.getKeyButton());
					buttons.put(colId, temp);
					//buttons.add(action.getKeyButton());
					if (action.isLeaf()) {
						String code = RequestUtil.getActionUrl(action.getCode());
						maps.put(colId, code);
						//actions.add(code);
					}
				}
			} else {
				if (actions.indexOf(action.getCode()) != -1) {
					actions.remove(action.getCode());
					Integer colId = action.getColumn().getId();
					if (buttons.containsKey(colId)) {
						List<String> temp = buttons.get(colId);
						temp.remove(action.getKeyButton());
						buttons.put(colId, temp);
					}
					//buttons.remove(action.getKeyButton());
					if (action.isLeaf()) {
						maps.remove(action.getColumn().getId());
						//actions.remove(RequestUtil.getActionUrl(action.getCode()));
					}
				}
			}
		}
		sessionInfo.setActions(actions);
		SessionContext myc= SessionContext.getInstance();
		myc.AddSession(sessionInfo);
		//菜单权限
		List<MenuDTO> menus = new ArrayList<MenuDTO>();
		List<ActionColumn> cols = this.getBaseDao().find("from ActionColumn ac order by ac.level asc, ac.id asc");
		Map<Integer, MenuDTO> dtos = new HashMap<Integer, MenuDTO>();
		Map<Integer, ActionColumn> acsMaps = new HashMap<Integer, ActionColumn>();
		List<ActionColumn> acsLst = new ArrayList<ActionColumn>();
		for (ActionColumn col : cols) {
			if (col.getLevel() == 1) {
				acsMaps.put(col.getId(), col);
			} else if (col.getLevel() == 2) {
				MenuDTO dto = new MenuDTO();
				dto.setId(col.getId());
				dto.setText(col.getName());
				dto.setNamespace(col.getNamespace());
				dto.setIcon("../manage/pic/menu/" + col.getIcon());
				ActionColumn parent = col.getParent();
				dto.setParent(parent.getId());
				dtos.put(col.getId(), dto);
				if (!acsLst.contains(parent)) acsLst.add(parent);
			} else {
				if (!maps.containsKey(col.getId())) continue;
				MenuDTO dto = dtos.get(col.getParent().getId());
				List<MenuDTO> children = dto.getChildren();
				MenuDTO dtootd = new MenuDTO();
				dtootd.setId(col.getId());
				dtootd.setText(col.getName());
				dtootd.setNamespace(col.getNamespace());
				dtootd.setBtns(this.join(buttons.get(col.getId())));
				dtootd.setIcon("../manage/pic/menu/" + col.getIcon());
				children.add(dtootd);
				dto.setChildren(children);
				dtos.put(col.getParent().getId(), dto);
			}
		}
		List<Integer> flagInt = new ArrayList<Integer>();
		Collection<MenuDTO> cs = dtos.values();
        for (MenuDTO c : cs) {
        	if (c.getChildren().size() > 0) {
        		menus.add(c);
        		flagInt.add(c.getParent());
        	}
        }
        List<MenuDTO> tops = new ArrayList<MenuDTO>();
        for (ActionColumn ac : acsLst) {
        	if (flagInt.contains(ac.getId())) {
        		MenuDTO md = new MenuDTO();
            	md.setId(ac.getId());
            	md.setText(ac.getName());
            	md.setIcon("../manage/pic/menu/" + ac.getIcon());
            	tops.add(md);
        	}
        }
        MenuDetailDTO dto = new MenuDetailDTO();
        dto.setMenus(menus);
        dto.setTops(tops);
		return JsonUtil.toStringFromObject(dto);
	}

	private String join(List<String> lst) {
		String res = "";
		for(String str : lst) {
			res += str + ";";
		}
		return res;
	}

	@Transactional(readOnly = true)
	public Map<String, Object> userinfo(HttpServletRequest request, HttpSession session) {
		SessionInfo sessionInfo = RequestUtil.getSession(request, session);
		User loginuser = sessionInfo.getUser();
		Map<String, Object> modelMap = new HashMap<String, Object>(4);
		modelMap.put("success", true);
		modelMap.put("username", loginuser.getUsername());
		modelMap.put("truename", loginuser.getTruename());
		modelMap.put("nickName", loginuser.getNickName());
		modelMap.put("lastTime", DateUtil.format(loginuser.getLastTime()));
		return modelMap;
	}

	@Transactional
	public Map<String, Object> logout(HttpSession session) {
		SessionContext myc = SessionContext.getInstance();
		myc.DelSession(session.getId());
		Map<String, Object> modelMap = new HashMap<String, Object>(1);
		modelMap.put("success", true);
		return modelMap;
	}
	
}
